package com.dbflow5.config;

import com.dbflow5.DemoApp;
import com.dbflow5.TestDatabase;
import com.dbflow5.database.*;

import com.dbflow5.BaseUnitTest;
import com.dbflow5.transaction.BaseTransactionManager;
import com.dbflow5.transaction.ITransactionQueue;
import com.dbflow5.transaction.Transaction;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.atomic.AtomicReference;

public class DatabaseConfigTest extends BaseUnitTest {
    private FlowConfig.Builder builder;

    public void setup() {
        FlowManager.reset();
        FlowLog.setMinimumLoggingLevel(FlowLog.Level.V);
        builder = new FlowConfig.Builder(getContext());
    }

    @Test
    public void test_databaseConfig() {
        setup();
        DatabaseCallback helperListener = new DatabaseCallback(){

            @Override
            public void onOpen(DatabaseWrapper database) {
            }

            @Override
            public void onCreate(DatabaseWrapper database) {
            }

            @Override
            public void onUpgrade(DatabaseWrapper database, int oldVersion, int newVersion) {
            }

            @Override
            public void onDowngrade(DatabaseWrapper databaseWrapper, int oldVersion, int newVersion) {
            }

            @Override
            public void onConfigure(DatabaseWrapper db) {
            }
        };
        OpenHelper customOpenHelper = new OpenHelper() {
            @Override
            public void setWriteAheadLoggingEnabled(boolean enabled) {

            }

            @Override
            public void setDatabaseListener(DatabaseCallback callback) {

            }

            @Override
            public void closeDB() {

            }

            @Override
            public void deleteDB() {

            }

            @Override
            public DatabaseWrapper database() {
                return null;
            }

            @Override
            public LocalDatabaseHelperDelegate delegate() {
                return null;
            }

            @Override
            public boolean isDatabaseIntegrityOk() {
                return false;
            }

            @Override
            public void performRestoreFromBackup() {

            }

            @Override
            public void backupDB() {

            }
        };

        DatabaseConfig.OpenHelperCreator openHelperCreator = (db, callback) -> customOpenHelper;

        AtomicReference<TestTransactionManager> testTransactionManager = new AtomicReference<>();
        DatabaseConfig.TransactionManagerCreator managerCreator = db -> {
            testTransactionManager.set(new TestTransactionManager(db));
            return testTransactionManager.get();
        };

        FlowManager.init(builder.database(TestDatabase.class, builder -> {
            builder.databaseName("Test");
            builder.helperListener(helperListener);
            builder.transactionManagerCreator(managerCreator);
            return null;
        }, openHelperCreator).build());

        FlowConfig flowConfig = FlowManager.getConfig();
        Assert.assertNotNull(flowConfig);

        DatabaseConfig databaseConfig = flowConfig.databaseConfigMap.get(TestDatabase.class);
        Assert.assertEquals("Test", databaseConfig.databaseName);
        Assert.assertEquals(".db", databaseConfig.databaseExtensionName);
        Assert.assertEquals(databaseConfig.transactionManagerCreator, managerCreator);
        Assert.assertEquals(databaseConfig.databaseClass, TestDatabase.class);
        Assert.assertEquals(databaseConfig.openHelperCreator, openHelperCreator);
        Assert.assertEquals(databaseConfig.callback, helperListener);
        Assert.assertTrue(databaseConfig.tableConfigMap.isEmpty());

        TestDatabase databaseDefinition = FlowManager.database(TestDatabase.class, testDatabase -> null);
        Assert.assertEquals(databaseDefinition.transactionManager, testTransactionManager.get());
        Assert.assertEquals(databaseDefinition.openHelper(), customOpenHelper);
    }

    @Test
    public void test_EmptyName() {
        builder=new FlowConfig.Builder(DemoApp.context);
        FlowManager.init(builder.database(TestDatabase.class, builder1 -> {
            builder1.databaseName("Test");
            builder1.extensionName("");
            return null;
        }, OhosSQLiteOpenHelper.createHelperCreator(getContext())).build());

        DatabaseConfig databaseConfig=FlowManager.getConfig().databaseConfigMap.get(TestDatabase.class);
        Assert.assertEquals("Test", databaseConfig.databaseName);
        Assert.assertEquals("", databaseConfig.databaseExtensionName);
    }

    static class TestTransactionManager extends BaseTransactionManager {
        public TestTransactionManager(DBFlowDatabase databaseDefinition){
            super(new ITransactionQueue() {
                @Override
                public void add(Transaction<?> transaction) {
                }

                @Override
                public void cancel(Transaction<?> transaction) {
                }

                @Override
                public void startIfNotAlive() {
                }

                @Override
                public void cancel(String name) {
                }

                @Override
                public void quit() {
                }
            }, databaseDefinition);
        }
    }
}
